<template>
    <div class="avatar-processor">
        <!-- 图片容器 -->
        <div ref="container" class="preview-container">
            <img ref="imageEl" :src="imgUrl" @load="initProcessor" crossorigin="anonymous" class="source-image" />
        </div>
        <!-- 操作区 -->
        <!-- <div class="controls">
            <button @click="downloadAvatar">下载超清头像</button>
            <label class="quality-range">
                画质调节:
                <input type="range" min="0.5" max="1" step="0.1" v-model.number="quality" />
                {{ Math.round(quality * 100) }}%
            </label>
        </div> -->
        <!-- 实时预览 -->
        <!-- <div v-if="previewUrl" class="preview-wrapper">
            <img :src="previewUrl" class="preview-image" />
        </div> -->
    </div>
</template>

<script setup>
import {onMounted, ref, watch} from "vue";

const props = defineProps({
    imgUrl: {type: String, required: true}, // 原始图片URL
    outputSize: {type: Number, default: 200}, // 输出尺寸（物理像素）
});

//子组件注册
const emits = defineEmits(["onImgUrlChange"]);
const container = ref(null);
const imageEl = ref(null);
const previewUrl = ref("");
const quality = ref(0.9);

// 核心处理器
const processAvatar = async () => {
    if (!imageEl.value?.complete) return;

    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d", {willReadFrequently: true});

    // 1. 分辨率计算
    const dpr = window.devicePixelRatio || 1;
    const targetSize = props.outputSize * dpr;
    canvas.width = targetSize;
    canvas.height = targetSize;

    // 2. 高质量渲染配置
    ctx.imageSmoothingEnabled = true;
    ctx.imageSmoothingQuality = "high";
    ctx.filter = "contrast(105%) saturate(110%)"; // 轻微画质增强

    // 3. 智能裁剪算法
    const img = imageEl.value;
    const [sx, sy, sw, sh] = calculateCoverArea(img.naturalWidth, img.naturalHeight, targetSize, targetSize);

    // 4. 绘制圆形蒙版 ()
    ctx.beginPath();
    ctx.arc(targetSize / 2, targetSize / 2, targetSize / 2, 0, Math.PI * 2);
    ctx.clip();

    // 5. 高清绘制
    ctx.drawImage(img, sx, sy, sw, sh, 0, 0, targetSize, targetSize);

    // 6. 锐化处理
    applySharpening(ctx, targetSize);

    // 7. 生成预览图
    previewUrl.value = canvas.toDataURL("image/webp", quality.value);
    return canvas;
};

// 计算object-fit: cover裁剪区域
const calculateCoverArea = (imgW, imgH, targetW, targetH) => {
    const targetRatio = targetW / targetH;
    const imgRatio = imgW / imgH;

    let sx, sy, sw, sh;

    if (imgRatio > targetRatio) {
        sw = imgH * targetRatio;
        sh = imgH;
        sx = (imgW - sw) / 2;
        sy = 0;
    } else {
        sw = imgW;
        sh = imgW / targetRatio;
        sx = 0;
        sy = (imgH - sh) / 2;
    }

    return [sx, sy, sw, sh];
};

// 锐化滤镜增强
const applySharpening = (ctx, size) => {
    const sharpenMatrix = [0, -0.2, 0, -0.2, 1.8, -0.2, 0, -0.2, 0];

    const tmpCanvas = document.createElement("canvas");
    const tmpCtx = tmpCanvas.getContext("2d");
    tmpCanvas.width = size;
    tmpCanvas.height = size;
    tmpCtx.drawImage(ctx.canvas, 0, 0);

    const imageData = tmpCtx.getImageData(0, 0, size, size);
    const pixels = imageData.data;

    for (let y = 1; y < size - 1; y++) {
        for (let x = 1; x < size - 1; x++) {
            const idx = (y * size + x) * 4;
            let r = 0,
                g = 0,
                b = 0;

            for (let ky = -1; ky <= 1; ky++) {
                for (let kx = -1; kx <= 1; kx++) {
                    const kidx = ((y + ky) * size + (x + kx)) * 4;
                    const weight = sharpenMatrix[(ky + 1) * 3 + (kx + 1)];

                    r += pixels[kidx] * weight;
                    g += pixels[kidx + 1] * weight;
                    b += pixels[kidx + 2] * weight;
                }
            }

            pixels[idx] = Math.min(255, Math.max(0, r));
            pixels[idx + 1] = Math.min(255, Math.max(0, g));
            pixels[idx + 2] = Math.min(255, Math.max(0, b));
        }
    }

    ctx.putImageData(imageData, 0, 0);
};

// 下载功能
const downloadAvatar = async () => {
    setTimeout(async () => {
        const canvas = await processAvatar();
        emits("onImgUrlChange", previewUrl.value);
        console.log("加载完毕");
    }, 1000);
    // const link = document.createElement("a");
    // link.download = `avatar-${Date.now()}.webp`;
    // link.href = canvas.toDataURL("image/webp", quality.value);
    // link.click();
};

// 响应式处理
onMounted(() => {
    downloadAvatar();
});

watch([quality, () => props.imgUrl], downloadAvatar);
</script>

<style scoped>
.avatar-processor {
    /* display: grid; */
    /* gap: 1.5rem; */
    height: 100%;
}

.preview-container {
    /* width: min(90vw, 400px);
    height: min(90vw, 400px); */
    width: 100%;
    height: 100%;
    border-radius: 50%;
    overflow: hidden;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
}

.source-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.controls {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    align-items: center;
}

/* .quality-range {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background: #f5f5f5;
    padding: 0.5rem 1rem;
    border-radius: 8px;
} */

.preview-wrapper {
    /* margin-top: 2rem; */
}

.preview-image {
    /* width: 200px;
    height: 200px; */
    width: 100%;
    height: 100%;
    border-radius: 50%;
    /* border: 3px solid #fff; */
    /* box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); */
}
</style>
